package jmu.edu.yjc.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import jmu.edu.yjc.Utils.ExcelImportValid;
import jmu.edu.yjc.exception.SystemException;
import jmu.edu.yjc.interfaces.SaveInterface;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author:yjc
 *
 * @Description: 导入数据通用监听器
 */

@Slf4j
public class MyExcelListener<T> extends AnalysisEventListener<T> {

    private Map<String, Object> param;
    //3000条保存一次数据
    private static final int BATCH_COUNT=3000;
    //数据缓存
    private List<T> list = new ArrayList<>(BATCH_COUNT);
    //mapper
    private SaveInterface<T> saveInterface;

    //public MyExcelListener(SaveInterface<T> saveInterface, Map<String, Object> param) {
    //    this.saveInterface = saveInterface;
    //    this.param = param;
    //}
    //构造器
    public MyExcelListener(SaveInterface<T> saveInterface) {
        this.saveInterface = saveInterface;
    }

    @Override
    public void invoke(T data, AnalysisContext analysisContext) {

        try {
            //通用方法数据校验
            ExcelImportValid.valid(data);
        }catch (SystemException e){
            // System.out.println(e.getMessage());
            //在easyExcel监听器中抛出业务异常
            throw new ExcelAnalysisException(e.getMessage());
        }
        log.info("解析到一条数据：{}",data.toString());
        //先将数据加到list中
        list.add(data);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list = new ArrayList<>(BATCH_COUNT);
        }
    }

    //最后再存储一次数据
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();

        //logger.info("所有数据解析完成！");
    }
    /**
     * 加上存储数据库
     */
    private void saveData() {
        //logger.info("{}条数据，开始存储数据库！", list.size());
        saveInterface.save(list,param);
        //logger.info("存储数据库成功！");
    }

}
